﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Max.PH6_2006A.LowCode.IService
{
    public interface IBaseService<TEntity, TInputDto, TOutputDto> where TEntity : class, new()
    {
        //这6个和仓储一样（偷懒）
        #region 同步方法
        /// <summary>
        /// 执行查询sql语句或存储过程，
        /// </summary>
        /// <param name="sql">sql语句或存储过程名称</param>
        /// <param name="param">参数[可选]</param>
        /// <param name="transcation">事务[可选]</param>
        /// <param name="buffered">是否将数据放入内存[可选]</param>
        /// <param name="commandTimeut">超时[可选]</param>
        /// <param name="commandType">sql语句类型（是sql语句还是存储过程）[可选]</param>
        /// <returns>返回单个对象</returns>
        TEntity QueryFirst(string sql,
                                        object? param = null,
                                        IDbTransaction? transcation = null,
                                        int? commandTimeut = null,
                                        CommandType? commandType = null);

        /// <summary>
        /// 执行查询sql语句或存储过程，
        /// </summary>
        /// <param name="sql">sql语句或存储过程名称</param>
        /// <param name="param">参数[可选]</param>
        /// <param name="transcation">事务[可选]</param>
        /// <param name="buffered">是否将数据放入内存[可选]</param>
        /// <param name="commandTimeut">超时[可选]</param>
        /// <param name="commandType">sql语句类型（是sql语句还是存储过程）[可选]</param>
        /// <returns>返回结果集</returns>
        IEnumerable<TEntity> Query(string sql,
                                        object? param = null,
                                        IDbTransaction? transcation = null,
                                        bool buffered = true,
                                        int? commandTimeut = null,
                                        CommandType? commandType = null);

        /// <summary>
        /// 执行查询sql语句或存储过程，
        /// </summary>
        /// <param name="sql">sql语句或存储过程名称</param>
        /// <param name="param">参数[可选]</param>
        /// <param name="transcation">事务[可选]</param>
        /// <param name="commandTimeut">超时[可选]</param>
        /// <param name="commandType">sql语句类型（是sql语句还是存储过程）[可选]</param>
        /// <returns>返回受影响行数</returns>
        int Execute(string sql,
                    object? param = null,
                    IDbTransaction? transcation = null,
                    int? commandTimeut = null,
                    CommandType? commandType = null);


        #endregion

        #region 异步方法
        /// <summary>
        /// 执行查询sql语句或存储过程，
        /// </summary>
        /// <param name="sql">sql语句或存储过程名称</param>
        /// <param name="param">参数[可选]</param>
        /// <param name="transcation">事务[可选]</param>
        /// <param name="commandTimeut">超时[可选]</param>
        /// <param name="commandType">sql语句类型（是sql语句还是存储过程）[可选]</param>
        /// <returns>返回单个对象</returns>
        Task<TEntity> QueryFirstAsync(string sql,
                                        object? param = null,
                                        IDbTransaction? transcation = null,
                                        int? commandTimeut = null,
                                        CommandType? commandType = null);

        /// <summary>
        /// 执行查询sql语句或存储过程，
        /// </summary>
        /// <param name="sql">sql语句或存储过程名称</param>
        /// <param name="param">参数[可选]</param>
        /// <param name="transcation">事务[可选]</param>
        /// <param name="commandTimeut">超时[可选]</param>
        /// <param name="commandType">sql语句类型（是sql语句还是存储过程）[可选]</param>
        /// <returns>返回结果集</returns>
        Task<IEnumerable<TOutputDto>> QueryAsync(string sql,
                                        object? param = null,
                                        IDbTransaction? transcation = null,
                                        int? commandTimeut = null,
                                        CommandType? commandType = null);

        /// <summary>
        /// 执行查询sql语句或存储过程，
        /// </summary>
        /// <param name="sql">sql语句或存储过程名称</param>
        /// <param name="param">参数[可选]</param>
        /// <param name="startTran">是否开户事务，默认false[可选]</param>
        /// <param name="commandTimeut">超时[可选]</param>
        /// <param name="commandType">sql语句类型（是sql语句还是存储过程）[可选]</param>
        /// <returns>返回受影响行数</returns>
        Task<int> ExecuteAsync(string sql,
                    object? param = null,
                    bool startTran = false,
                    int? commandTimeut = null,
                    CommandType? commandType = null);

        #endregion

        #region 基本的操作（用上面的同步或异步方法：执行sql语句和查询sql语句就可以满足）
        //1、列表
        //Task<IEnumerable<TOutputDto>> QueryAsync(string sql, object param = null);

        //2、添加，指定表名
        Task<int> InsertAsync(TInputDto entity, string tableName);

        //添加（用反射获取表名）
        Task<int> InsertAsync(TEntity t);


        //3、单删除批删除都可以用（在前台vue中，哪个传值更方便）
        Task<int> DeleteAsync(List<string> ids, string tableName);  //根据id删除

        Task<int> DeleteAsync(List<TEntity> list);  //根据模型删除

        //4、修改
        Task<int> UpdateAsync(TEntity entity);

        #endregion


        #region //新定义的

        /*
         * 查询所有信息，返回指定实体
         * Date：2023/2/8
         * **/        
        Task<Tuple<IEnumerable<TEntity>, int>> QueryAsync(int pageIndex, int PageSize, string sql, object? param = null, IDbTransaction? transcation = null, int? commandTimeut = null, CommandType? commandType = null);

        /*
         * 多表联查，各种字段都有，不写dto，就直接用dynamic
         * Date：2023/2/13
         * **/
        Task<Tuple<IEnumerable<dynamic>, int>> QueryDynamicAsync(int pageIndex, int PageSize, string sql, object? param = null);


        #endregion
    }
}
